#if !defined(SM__GAME_H)
#define SM__GAME_H

#include "SDL.h"

class Display;
class Player;
class Scene;
#include "Sprite.h"
#include "Swag.h"
#include "Npc.h"
#include <vector>
#include <map>
#include <string>
#include <deque>
#include "collide.h"
#include "sound.h"

// Game class to encapsulate the whole game
class Game 
{
  private:
    Sint32 mTimeLeftInSec;
    Uint32 mStartTimeInMs;

    Display* mpDisplay;
    Scene*   mpScene;
    Player*  mpPlayer;
    map<string, Sprite *> mSprites;
    vector<Swag *> mSwaggage;
    typedef vector<Swag *>::iterator SwagIter;
    vector<Npc *> mNonplayers;
    typedef vector<Npc *>::iterator NpcIter;
    DummyWall theWall;

    // WARNING: this container DOES NOT own the TouchableObjects - these objects are 
    // owned by mpPlayer, mSwaggage, and mNonplayers and should be de-allocated 
    // there after emptying this function...
    vector<TouchableObject*> mRenderables;

    XMLNode* mpConfig;

    NodeArray mAllLevels;
    XMLNode* mpCurLevel;

    CollisionMap mColMap;

    void Init();
    void InitSprites();
    void InitSounds();
    void InitScene();
    void DrawScene();
    void DrawBackground();
    void DrawFloor();
    void DrawScreen();

    // renders the status area (called from Update())
    void DrawStatus();

    // map edge collision detection & reaction
    int boundsCheck(int x, int y, int &fixedX, int &fixedY);
    int collisionTest(int x1, int y1, int x2, int y2);
    XMLNode* InitConfig(const char* szConfigFilename);

    int crunchCollisionMap(SDL_Surface *s);
    void dumpColMap();

    bool mbResortRenderables; // dirty flag so the renderable objects array is resorted only on movement
    Sound* sound;

    deque<sm_direction> mKeyPressStack;
    typedef deque<sm_direction>::iterator KeyIter;
    bool mbUpKeyPressed;
    bool mbRightKeyPressed;
    bool mbDownKeyPressed;
    bool mbLeftKeyPressed;
  public:
    Game();
    ~Game();

    bool IsGameOver() const { return (mTimeLeftInSec <= 0); }

    // called every game loop 
    void Update(Uint8* keystate);

    XMLNode* getConfig() { return mpConfig; }
};

#endif // SM__GAME_H
